import React, { Component } from 'react';
import { Row, Col, Form, Select, Checkbox, Icon, Upload, Input, Modal, Table, InputNumber, Radio, message } from 'antd';

import { Relax } from 'iflux2';
import { Map, List } from 'immutable';

//table columns
import listColumns from '../constant/columns-buy-goodsList';
import FixedSubmit from '../../../../web_modules/components/fixed-submit';
import { AfterSaleOptionType, HideOptionType } from '../constant/action-type';

import { routerShape } from 'constant/PropTypes';
import { createLocationDescriptor } from 'util/history';
import noop from 'util/noop'

const FormItem = Form.Item;
const Option = Select.Option;
const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group;

@Relax
export default class ReturnInfo extends Component {
    static defaultProps = {
        order: Map(),
        afterSaleOptions: List(),
        ordersList: List(),
        applyAfterSale: noop
    };

    render() {
        return (<ReturnInfoForm {...this.props} />)
    }
}

class ReturnInfoForm extends Component {

    //路由跳转
    static contextTypes = {
        router: routerShape
    }

    constructor(props) {
        super(props);
        this.state = {
            selectedRowKeys: [],
            applyReturnItemNumMap: {},
            applyEvidence: [],
            hasChangedCash: false
        }
    }

    componentDidMount() {
        this.setState({
            applyReturnItemNumMap: this.init(this.props.order.get('itemOrders'))
        });
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            applyReturnItemNumMap: this.init(nextProps.order.get('itemOrders'))
        });
    }

    init(itemOrders = []) {
        let map = Object.assign({}, this.state.applyReturnItemNumMap)
        itemOrders.forEach(itemOrder => {
            if (typeof map[itemOrder.get('oid')] !== 'number') {
                map[itemOrder.get('oid')] = itemOrder.get('itemNumber') - (itemOrder.get('returnedItemNum') || 0)
            }
        })
        return map;
    }



    render() {
        const { order } = this.props;
        const { selectedRowKeys } = this.state;

        const rowSelection = {
            selectedRowKeys: selectedRowKeys,
            onChange: this.selectChange,
            onSelectAll: this.selectAll,
            getCheckboxProps: record => ({
                disabled: record.itemNumber === record.returnedItemNum
            })
        };

        return (
            <div>
                <div className="buy-list">
                    <Table
                        dataSource={(order.get("itemOrders") || List()).toJS()}
                        rowKey={'oid'}
                        columns={this.renderColumns()}
                        rowSelection={rowSelection}
                        pagination={false}
                    />
                </div>
                <Row className="bg-white">
                    <Col span={18}>
                        <Form className="return-info" horizontal >
                            {this.renderAfterSaleOptions()}
                        </Form>
                        <FixedSubmit cancel={this.handleCancel} save={this.handleSumbit} />
                    </Col>
                </Row>
            </div>
        )
    }

    renderColumns = () => {
        let columns = listColumns.slice()
        columns.splice(2, 2, {
            title: "退货数量",
            width: 100,
            className: "ant-table-th-center va-t",
            dataIndex: "buyNum",
            render: (v, record, index) => {
                let maxReturnedItemNum = record.itemNumber - (record.returnedItemNum || 0);
                return (
                    <div className="buy-num">
                        <InputNumber min={0} max={maxReturnedItemNum} value={this.state.applyReturnItemNumMap[record.oid]}
                            disabled={maxReturnedItemNum === 0}
                            className="t-center" onChange={(value) => this.changeReturnItem(value, record.oid, maxReturnedItemNum)} />
                        <p className="t-center t-grayer mt3">最多可选{maxReturnedItemNum}件</p>
                    </div>
                )
            }
        }, {
                title: "实付金额（可退）",
                width: 250,
                className: "ant-table-th-center",
                dataIndex: "realPay",
                render: (v, record, index) => {
                    let total = record.pervalue * (this.state.applyReturnItemNumMap[record.oid]);
                    total = this.round(total);
                    return <div className="t-center t-price font-14">&yen;{total}</div>
                }
            })
        return columns;
    }

    /**
     * 退货相关选项
     */
    renderAfterSaleOptions() {
        const { afterSaleOptions } = this.props;
        let arr = afterSaleOptions.toJS()
            .filter(option => option.isShow === 1 && HideOptionType.indexOf(option.typeId) < 0)
            .map(option => {
                switch (option.typeId) {
                    case AfterSaleOptionType.RETURN_REASON:
                        return this.renderReturnReason(option);
                    case AfterSaleOptionType.RETURN_CASH:
                        return this.renderReturnCash(option);
                    case AfterSaleOptionType.RETURN_PROBLEM:
                        return this.renderReturnProblem(option);
                }
            })
            .map(val =>
                <FormItem label={val.attrDesc} required={val.isNeed === 1} {...this.formItemLayout() } >
                    {val.field}
                </FormItem>)
        return arr;
    }

    /**
     * 退货原因
     * @param {*} option 
     */
    renderReturnReason(option) {
        const { form: { getFieldDecorator } } = this.props;
        const opts = (option.attrContent || '').split(',').map((opt, index) => ({ value: opt, name: opt, key: index + 1 }));
        if (option.isNeed !== 1) {
            opts.splice(0, 0, { value: '', name: '请选择退货原因', key: 0 })
        }
        const field = getFieldDecorator('returnReason', {
            initialValue: opts[0].value
        })(
            <Select id="select" size="large" placeholder="请选择退货原因" className="w180">
                {
                    opts.map((item, index) => <Option value={item.value} key={item.key}>{item.name}</Option>)
                }
            </Select>
            );
        return { attrDesc: option.attrDesc, field, isNeed: option.isNeed };
    }

    /**
     * 申请票据（D侧不展示）
     * @param {*} option 
     */
    renderApplyEvidence(option) {
        const { form: { getFieldDecorator } } = this.props;
        const opts = (option.attrContent || '').split(',').map(value => { return { label: value, value } });
        const rules = option.isNeed === 1 ? [
            {
                required: true, message: '请至少选择一项'
            }, {
                validator: this.checkApplyEvidence
            }
        ] : null;
        const field = getFieldDecorator('evidence', { rules })(
            <div>
                <CheckboxGroup options={opts} onChange={this.changeApplyEvidence} ></CheckboxGroup>
            </div>
        );
        return { attrDesc: option.attrDesc, field, isNeed: option.isNeed };
    }

    /**
     * 退款金额
     * @param {*} option 
     */
    renderReturnCash = (option) => {
        const { form: { getFieldDecorator } } = this.props;
        let totalCash = this.calculate(this.state.selectedRowKeys);
        //退款金额
        const field = getFieldDecorator('applyReturnCash', {
            initialValue: 0
        })(
            <Input className="w180" onBlur={this.handleReturnCash} />
            );
        return { attrDesc: option.attrDesc, field: <p>{field}<span className="ant-form-text">元&nbsp;&nbsp;(最多可退{totalCash || 0}元)</span></p>, isNeed: option.isNeed };
    }

    /**
     * 问题说明
     * @param {*} option 
     */
    renderReturnProblem(option) {
        const { form: { getFieldDecorator } } = this.props;
        const field = getFieldDecorator('returnProblem', {
            rules: [
                {
                    validator: option.isNeed === 1 ? this.checkReturnProblem : null
                }
            ]
        })(
            <Input type="textarea" maxLength={200} placeholder="请输入备注内容" rows="3" cols="4" className="w460" />
            );
        return { attrDesc: option.attrDesc, field, isNeed: option.isNeed };
    }

    /**
     * 退货方式（D侧不展示）
     * @param {*} option 
     */
    renderShipType(option) {
        let opts = (option.attrContent || '').split(',');

        const { form: { getFieldDecorator } } = this.props;
        const field = getFieldDecorator('shipType', {
            initialValue: option.isNeed === 1 ? opts[0] : null,
        })(
            <RadioGroup>
                {
                    opts.map((v, k) => {
                        return <Radio value={v} key={k}>{v}</Radio>
                    })
                }
            </RadioGroup>
            );
        return { attrDesc: option.attrDesc, field, isNeed: option.isNeed };
    }

    formItemLayout() {
        return {
            labelCol: { span: 3 },
            wrapperCol: { span: 21 }
        };
    }

    /**
     * 全选操作
     * @param selected
     * @param selectedRows
     * @param changeRows
     */
    selectAll = (selected, selectedRows, changeRows) => {
        let selectedRowKeys = [];
        selected && selectedRows.forEach(row => selectedRowKeys.push(row.oid));
        this.setState({ selectedRowKeys });
        this.syncApplyReturnCash(selectedRowKeys);
    }

    /**
     * 选择/取消
     */
    selectChange = (selectedRowKeys) => {
        this.setState({ selectedRowKeys });
        this.syncApplyReturnCash(selectedRowKeys);
    }

    /**
     * 修改商品退货数量时触发的事件
     */
    changeReturnItem = (num, oid, maxReturnedItemNum) => {
        if (typeof num !== 'number' || num < 0 || num > maxReturnedItemNum) {
            num = maxReturnedItemNum;
        } else {
            num = parseInt(num);
        }
        let map = Object.assign({}, this.state.applyReturnItemNumMap);
        map[oid] = num;
        this.setState({
            applyReturnItemNumMap: map
        }, () => {
            this.syncApplyReturnCash(this.state.selectedRowKeys, map)
        });
    }

    /**
     * 退货商品发生变化时，自动计算应退金额并设置。
     * 如果用户手动修改过退款金额，就不再自动设置
     * @param {*} selectedRowKeys 选中的商品
     * @param {*} map 商品的数量
     */
    syncApplyReturnCash(selectedRowKeys, map) {
        const { setFieldsValue, getFieldValue } = this.props.form;
        let totalCash = this.calculate(selectedRowKeys, map);
        let applyReturnCash = Number(getFieldValue('applyReturnCash') || 0)
        if (!this.state.hasChangedCash || applyReturnCash === 0 || applyReturnCash > Number(totalCash || 0)) {
            setFieldsValue({ 'applyReturnCash': totalCash })
        }
    }

    /**
     * 根据选中的商品和商品数量计算应该退的金额
     * @param selectedRowKeys 选中的商品
     * @param map 商品的数量，如果为空，直接从this.state中取applyReturnItemNumMap
     */
    calculate = (selectedRowKeys, map) => {
        if (selectedRowKeys.length === 0) {
            return 0;
        }
        let order = this.props.order;
        let itemOrders = order.get('itemOrders')
        let cash = itemOrders.filter(order => selectedRowKeys.indexOf(order.get('oid')) >= 0)
            .map(order => {
                return order.get('pervalue') * (map || this.state.applyReturnItemNumMap)[order.get('oid')]
            })
            .reduce((prev, cur) => prev + cur);
        // 已选商品最大可退金额
        let itemCash = this.round(cash);
        // 订单最大可退金额 = 订单已支付金额 - 订单已退金额 （积分抵扣、运费不退 2017/04/27确认）
        let tradeMaxCash = this.round(Number(order.get('payTradeFee')) - Number(order.get('logisticsFee')) - Number(order.get('invoiceFee')) - Number(order.get('acctRefundFee')));
        // 由于存在积分抵扣，可能会出现itemMaxCash大于tradeMaxCash的情况，这时最大只能退tradeMaxCash
        return itemCash > tradeMaxCash ? tradeMaxCash : itemCash;
    }

    changeApplyEvidence = (value) => {
        this.setState({ applyEvidence: value });
    }

    checkApplyEvidence = (rule, applyEvidence, callback) => {
        if (!applyEvidence && this.state.applyEvidence.length <= 1) {
            callback('请至少选择一项');
        } else {
            callback()
        }
    }

    handleSumbit = (e) => {
        e.preventDefault();
        if (this.state.selectedRowKeys.length == 0) {
            message.warn('请选择需要退货的商品', 2)
            return;
        }
        let total = 0;
        let applyReturnItemRequestList = [];
        this.state.selectedRowKeys.forEach(oid => {
            total += this.state.applyReturnItemNumMap[oid];
            if (this.state.applyReturnItemNumMap[oid] !== 0) {
                applyReturnItemRequestList.push({ oid, itemnum: this.state.applyReturnItemNumMap[oid] })
            }
        })

        if (total === 0) {
            message.warn('商品数量不能为0', 2);
            return;
        }

        this.props.form.validateFields((err, fieldsValue) => {
            if (err) {
                return;
            }
            const params = {
                ...fieldsValue,
                tid: this.props.order.get('tid'),
                applyReturnItemRequestList,
                applyEvidence: this.state.applyEvidence.join(',')
            };

            this.props.applyAfterSale(params).then(result => {
                this.context.router.replace(createLocationDescriptor('/order/list/sales'));
            });
        })
    }

    handleCancel = () => {
        this.context.router.replace(createLocationDescriptor('/order/list/sales'));
    }

    /**
     * 手动修改退款金额时触发的事件
     */
    handleReturnCash = (e) => {

        if (!this.state.hasChangedCash) {
            // 标识已手动修改过。退货商品发生变化时不再同步退款金额
            this.setState({
                hasChangedCash: true
            });
        }

        const { getFieldValue, setFieldsValue } = this.props.form;
        let value = e.target.value;
        let cash = 0;
        let maxCash = this.calculate(this.state.selectedRowKeys);
        if (isNaN(value)) {
            cash = maxCash;
        } else {
            cash = this.round(Number(value));
            if (cash < 0 || cash > maxCash) {
                cash = maxCash
            }
        }
        setFieldsValue({ 'applyReturnCash': cash })
    }

    /**
     * 校验问题说明
     */
    checkReturnProblem = (rule, returnProblem, callback) => {
        if ((returnProblem || '').trim() === '') {
            callback('问题说明不能为空')
        } else {
            callback()
        }
    }

    round = (value) => {
        // 只保留两位小数
        let num = (value || 0).toFixed(2);
        // 避免出现整数带.00的情况
        return parseInt(Number(num) * 100, 10) / 100;
    }

}

ReturnInfoForm = Form.create()(ReturnInfoForm);
